import { CommonModule, NgFor, NgIf } from '@angular/common';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ChangeDetectorRef, Component, Inject, inject, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { finalize, map, Observable, Observer, Subscription } from 'rxjs';

import { RequestParams } from '@app/core/domain/request-params';
import { TabService } from '@app/core/services/common/tab.service';
import { BaseHttpService } from '@app/core/services/http/base-http.service';
import { CardInfo, CardInfoService } from '@app/core/services/http/card-info/card-info.service';
import { ImportResult, OperationService, Status } from '@app/core/services/http/operation/operation.service';
import { AntTableComponent, AntTableConfig } from '@app/shared/components/ant-table/ant-table.component';
import { CardTableWrapComponent } from '@app/shared/components/card-table-wrap/card-table-wrap.component';
import { PageHeaderType } from '@app/shared/components/page-header/page-header.component';
import { SharedModule } from '@app/shared/shared.module';
import { environment, localUrl } from '@env/environment.prod';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzMessageRef, NzMessageService } from 'ng-zorro-antd/message';
import { NzModalModule } from 'ng-zorro-antd/modal';
import { NzPaginationModule } from 'ng-zorro-antd/pagination';
import { NzProgressModule } from 'ng-zorro-antd/progress';
import { NzTableQueryParams } from 'ng-zorro-antd/table';
import { NzTabsModule } from 'ng-zorro-antd/tabs';
import { NzUploadChangeParam, NzUploadFile } from 'ng-zorro-antd/upload';

@Component({
  selector: 'app-card-scan',
  standalone: true,
  imports: [SharedModule, CardTableWrapComponent, AntTableComponent, NzPaginationModule, NzProgressModule, NzModalModule, NgFor, NgIf, CommonModule, NzTabsModule],
  templateUrl: './card-scan.component.html',
  styleUrl: './card-scan.component.less'
})
export class CardScanComponent implements OnInit {
  validateForm!: FormGroup;
  fileList: NzUploadFile[] = [];
  fileIndex = 0;
  avatarUrl: string = '';
  uploading: boolean = false;
  tableConfig!: AntTableConfig;
  uploadUrl = `/Operation/Scan/ScanZip`;
  uploadImgUrl = '/Operation/Scan/ScanImages';
  cardInfos: CardInfo[] = [];
  isLoading: boolean = false;
  currentPercentage: number = 0;
  importResult!: ImportResult;
  tableResult!: Status;
  showMessages: string[] = [];
  currentMessageIndex: number = 1;
  messageSize: number = 5;
  pageHeaderInfo: Partial<PageHeaderType> = {
    title: '卡号识别',
    breadcrumb: ['首页', '功能菜单', '卡号识别']
  };
  isVisibleResult: boolean = false;
  messageRef?: NzMessageRef;
  message: NzMessageService = inject(NzMessageService);
  http: BaseHttpService = inject(BaseHttpService);
  httpClient: HttpClient = inject(HttpClient);
  cdr: ChangeDetectorRef = inject(ChangeDetectorRef);
  tabIndex: number = 0;
  operationService: OperationService = inject(OperationService);
  private readonly cardInfoService: CardInfoService = inject(CardInfoService);

  private initTable(): void {
    this.tableConfig = {
      headers: [
        {
          title: '卡号',
          width: 130,
          field: 'cardnumber',
          show: true,
          showSort: true
        },
        {
          title: '卡密',
          width: 130,
          field: 'cardpassword',
          show: true,
          showSort: true
        }
      ],
      total: 0,
      showCheckbox: false,
      loading: false,
      pageSize: 10,
      pageIndex: 1
    };
  }

  changeTab(index: number): void {
    this.tabIndex = index;
  }

  tableChangeDectction(): void {
    this.cardInfos = [...this.cardInfos];
    this.cdr.detectChanges();
  }

  tableLoading(isLoading: boolean): void {
    this.tableConfig.loading = isLoading;
    this.tableChangeDectction();
  }

  appendRequestParams(): RequestParams {
    const filter: Partial<CardInfo> = {};
    let requestParams: RequestParams = {
      '@relationships': 'LoginInfo,Password',
      current: this.tableConfig.pageIndex,
      pageSize: this.tableConfig.pageSize,
      '@filter': '',
      ...filter
    };

    return requestParams;
  }

  getCardInfo(e?: NzTableQueryParams): void {
    if (!this.isLoading) {
      return;
    }

    if (e) {
      this.tableConfig.pageIndex = e?.pageIndex;
    }
    this.tableConfig.loading = true;
    let requestParams: RequestParams = this.appendRequestParams();

    this.cardInfoService
      .getEntityPageList(requestParams)
      .pipe(
        finalize(() => {
          this.tableLoading(false);
        })
      )
      .subscribe(cardInfos => {
        const { records, total } = cardInfos;
        this.cardInfos = records;
        this.tableConfig.total = total;
      });
  }

  changePageSize(e: number): void {
    this.tableConfig.pageSize = e;
  }

  exportWordFile(): void {
    this.httpClient.get(environment.production ? '/daemonApi/Operation/ExportWord' : `${localUrl}/Operation/ExportWord`, { responseType: 'blob' }).subscribe(data => {
      const blob = new Blob([data], { type: data.type });
      window.open(URL.createObjectURL(blob));
    });
  }

  beforeUpload = (file: NzUploadFile, _fileList: NzUploadFile[]): Observable<boolean> =>
    new Observable((observer: Observer<boolean>) => {
      const isZipFile = file.type === 'application/x-zip-compressed';
      const isRarFile = file.type === 'application/x-rar-compressed';
      if (!isZipFile && !isRarFile) {
        this.message.error('只能上传zip或rar格式的文件!');
        observer.complete();
        return;
      }
      observer.next(isZipFile || isRarFile);
      observer.complete();
    });

  validateImageUpload = (file: NzUploadFile, _fileList: NzUploadFile[]): Observable<boolean> => {
    return new Observable((observer: Observer<boolean>) => {
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
      console.log(_fileList);
      if (!isJpgOrPng) {
        this.message.error('只能上传JPG或PNG格式的图片!');
        observer.complete();
        return;
      }
      this.fileIndex++;
      if (this.fileIndex === _fileList.length) {
        this.fileList = _fileList;
        observer.next(isJpgOrPng);
        observer.complete();
      }
    });
  };

  handleChange({ file, fileList }: NzUploadChangeParam): void {
    const status = file.status;
    if (status !== 'uploading') {
      console.log(file, fileList);
    }
  }

  customRequest = (item: any): Subscription => {
    const formData = new FormData();
    formData.append(this.tabIndex === 0 ? 'file' : 'files', item.file);

    this.isLoading = true;
    this.messageRef = this.message.loading('开始上传数据...', { nzDuration: 0 });
    // 使用 HttpClient 发送请求
    return this.http.upload<NzSafeAny>(this.tabIndex === 0 ? this.uploadUrl : this.uploadImgUrl, formData).subscribe(result => {
      this.importResult = result[0];
      this.refreshImport().then(result => {
        this.initErrorMessage();
        this.tableResult = result as Status;
        console.log(this.tableResult);
        this.message.success('导入成功！');
        this.tableConfig.pageIndex = 1;
        this.getCardInfo();
        this.cdr.detectChanges();
        this.cdr.markForCheck();
        this.fileList = [];
      });
    });
  };

  initErrorMessage(): void {
    this.showMessages = [];
    const allMessages: string[] = this.importResult.status.currenttableresult.messages;
    if (allMessages.length > 10) {
      for (let index = (this.currentMessageIndex - 1) * this.messageSize; index < this.currentMessageIndex * this.messageSize; index++) {
        this.showMessages.push(allMessages[index]);
      }
    } else {
      this.showMessages = allMessages;
    }
  }

  messagePageChange(): void {
    this.initErrorMessage();
  }

  refreshImport(): Promise<unknown> {
    let finishResolve,
      finishPromise = new Promise(resolve => {
        finishResolve = resolve;
      });

    this.refreshImportStatus(this.importResult.id, finishResolve);
    return finishPromise;
  }

  previewImg(imgUrl: string): void {
    window.open(imgUrl, '_blank');
  }

  refreshImportStatus(operationId: string, resolve: any): void {
    this.operationService.getOperationResult(operationId).subscribe((result: ImportResult[]) => {
      if (result[0].status.currenttableresult.finished) {
        resolve(result[0].status);
        this.importResult = result[0];
        this.currentPercentage = 100;
        this.isVisibleResult = true;
        this.message.remove(this.messageRef?.messageId);
        return;
      }

      this.calculateProcessPercentage(result[0]);
      setTimeout(() => {
        this.refreshImportStatus(operationId, resolve);
      }, 1000);
    });
  }

  handleOk(): void {
    if (this.currentPercentage !== 100) {
      this.message.error('正在识别图片....');
      return;
    }

    this.showMessages = [];
    this.isVisibleResult = false;
  }

  handleCancel(): void {
    if (this.currentPercentage !== 100) {
      this.message.error('正在识别图片....');
      return;
    }

    this.isVisibleResult = false;
    this.showMessages = [];
  }

  calculateProcessPercentage(importResult: ImportResult): void {
    const { status } = importResult;
    const currentTableResult = status.currenttableresult;
    if (!currentTableResult) {
      return;
    }

    const currentPercentage = parseFloat(Math.min(0.99, currentTableResult.totalsourcecount ? currentTableResult.processedcount / currentTableResult.totalsourcecount : 0).toFixed(2));
    this.currentPercentage = parseFloat(Math.min(0.99, currentPercentage).toFixed(2)) * 100;
    this.currentPercentage = parseFloat(this.currentPercentage.toFixed(2));
    if (this.currentPercentage > 0) {
      this.isVisibleResult = true;
      this.message.remove(this.messageRef?.messageId);
    }
    this.cdr.detectChanges();
  }

  ngOnInit(): void {
    this.initTable();
  }
}
